package com.lincs.web.part1.test;

import com.lincs.web.part1.mybatis.po.User;
import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * <p>标题：</p>
 * <p>功能：</p>
 * <pre>
 * 其他说明：
 * </pre>
 * <p>作者：林昌胜</p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2020-08-04-21:05</p>
 * 查看帮助：<a href="" target="_blank"></a>
 */
public class MybatisV1 {
    private Properties properties=new Properties();
    private static final String DB_SQL_PRE = "db.sql.";
    private static final String DB_SQL_COLUMN = ".columnnames";
    private static final String DB_SQL_RESULTTYPE = ".resulttype";

    @Test
    public void mybatisTest() {
        //1:加载properties配置文件中的内容
        loadProperties("jdbc.properties");
//        System.out.println("根据ID查询用户");
//        List<User> users=findUser("queryUserById",3);
        System.out.println("根据用户名查询用户");
        List<User> users = findUser("queryUserByName","中国老腊肉");
//        System.out.println("根据用户名和性别查询用户");
//        Map<String,Object> param = new HashMap<>();
//        param.put("username","中国老腊肉");
//        param.put("sex","女");
//        List<User> users = findUser("queryUserByParams",param);
        if(users!=null&&users.size()>0){
            for(int i=0;i<users.size();i++){
                User vo=users.get(i);
                System.out.println(i+"--用户信息：【id-"+vo.getId()+",username-"+vo.getUsername()+"】");
            }
        }
    }

    private void loadProperties(String filePath) {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath);
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public <T> List<T> findUser(String statementId, Object params) {
        List<T> results=new ArrayList<T>();
        Connection conn = null;
        PreparedStatement preState = null;
        ResultSet rs = null;
        try {
            //Class.forName(properties.getProperty("db.driver"));//加载数据库驱动
            //解决获取连接时的硬编码问题和频繁连接问题
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(properties.getProperty("db.driver"));
            dataSource.setUrl(properties.getProperty("db.url"));
            dataSource.setUsername(properties.getProperty("db.username"));
            dataSource.setPassword(properties.getProperty("db.password"));
            //建立连接
            //conn = DriverManager.getConnection(properties.getProperty("db.url"), properties.getProperty("db.username"), properties.getProperty("db.password"));
            conn = dataSource.getConnection();
            String sql = properties.getProperty(DB_SQL_PRE + statementId);
            //预处理statement
            preState = conn.prepareStatement(sql);
            if (params instanceof Integer || params instanceof String) {
                preState.setObject(1, params);
            } else if (params instanceof Map) {
                Map<String, Object> paramsMap=(Map<String,Object>)params;
                String colunnames=properties.getProperty(DB_SQL_PRE+statementId+DB_SQL_COLUMN);
                String[] colunnamesArr=colunnames.split(",");
                if(colunnamesArr!=null&&colunnamesArr.length>0){
                    for(int i=0;i<colunnamesArr.length;i++){
                        preState.setObject(i+1,paramsMap.get(colunnamesArr[i]));
                    }
                }
            } else {
                System.out.println("暂不支持该入参类型");
                throw new RuntimeException("暂不支持该入参类型");
            }
            rs = preState.executeQuery();//查询结果集
            //获取返回结果类型--路径
            String resultType=properties.getProperty(DB_SQL_PRE+statementId+DB_SQL_RESULTTYPE);
            Class<?> clazz=Class.forName(resultType);
            //通过构造函数创建对象--返回对象类型
            Constructor<?> constructor=clazz.getDeclaredConstructor();
            Object result=null;
            while (rs.next()) {
                result=constructor.newInstance();
                //结果集中列信息
                ResultSetMetaData metaData=rs.getMetaData();
                int columnCount=metaData.getColumnCount();//列数
                for(int i=0;i<columnCount;i++){
                    String columnName=metaData.getColumnName(i+1);
                    //通过反射给指定列对应的属性名称赋值，列名必须与属性名一致
                    Field field=clazz.getDeclaredField(columnName);
                    //暴力破解，破坏封装，可以访问私有成员
                    field.setAccessible(true);
                    field.set(result,rs.getObject(columnName));
                }
                results.add((T) result);
                //System.out.println(rs.getString("id") + "-" + rs.getString("username"));
            }
        } catch (Exception e) {
            System.out.println("数据库访问异常！");
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (preState != null) {
                    preState.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                System.out.println("回收资源，关闭链接时发生异常");
                e.printStackTrace();
            }
        }
        return results;
    }
}